home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR02 / DCGAMES1.ZIP / NEWGAME.ZIP / CONTROL.SCR < prev    next >
Text File  |  1993-01-24  |  17KB  |  534 lines

  1. !
  2. ! CONTROL.SCR
  3. !
  4. ! This script manages some independent functions of the game system.  The
  5. ! script is called by the game driver at certain points during game play,
  6. ! and the entry points are numeric (@0, @1, @2..) instead of the usual entry
  7. ! points (@TALK, @GET, ..).
  8. !
  9. ! QUICK SUMMARY OF ENTRY POINTS:
  10. !
  11. ! :@0 - Time Control.  Executed once every minute (game time).
  12. ! :@1 - Resting.       Executed when party decides to rest ('C'amp-Out)
  13. ! :@2 - Leave Party.   Removes a party member. ('V'acate command)
  14. !
  15.  
  16. !---------------------------------------------------------------------------!
  17. :@0 ! Entry Point @0 : Time Control Script                                  !
  18. !---------------------------------------------------------------------------!
  19. !
  20. ! This script will start execution at this label once per minute during
  21. ! regular play.  This does not include battles or when the party is resting.
  22. !
  23. ! Time is controled by seting the following variables from any script:
  24. !
  25. !   Variable             Default  Description
  26. !   -------------------  -------  --------------------------------
  27. !   MovesPerMinute             2  # of moves per game 'minute'
  28. !   MinutesInAnHour           60  # of minutes in an game 'hour'
  29. !   HoursInADay               24  # of hour in a game 'day'
  30. !   DaysInAMonth              30  # of days in a game 'month'
  31. !   MonthsInAYear             12  # of months in a game 'year'
  32. !   
  33. ! The CURRENT time is obtained (and modified) by setting the following
  34. ! variables:
  35. !
  36. !   year                 Current Year   (Range -32767 to 32767)
  37. !   month                Current Month  (Range 0 to MonthsInAYear - 1)
  38. !   day                  Current Day    (Range 0 to DaysInAMonth  - 1)
  39. !   hour                 Current Hour   (Range 0 to HoursInADay   - 1)
  40. !   minute               Current Minute (Range 0 to MinutesInADay - 1)
  41. !
  42. ! Note that the year, month, day, hour and minute variables are automaticly
  43. ! updated by the game driver, but you can modify these variables just like
  44. ! any other one.
  45. !
  46.  
  47.   L255 = group.current; ! Save current party spokesperson   !
  48.   L254 = FALSE;         ! Have NOT created a random monster !
  49.  
  50.   dec( group.energy );  ! Get Tired !
  51.  
  52. ! Once an hour.. !
  53. if minute = 0 then 
  54.   ! Create a random monster 1 out of every 5 times (approx) !
  55.   if random(5) = 0 then
  56.     if world.type = OUTDOORS or world.type = DUNGEON or world.type = HAUNTED then
  57.       gosub NEWMONSTER;
  58.     endif;
  59.   endif;
  60.   ! Check to see if you have food.. !
  61.   if group.food <= group.size then
  62.     if group.food = 0 then
  63.       writeln( "You have no food.." );
  64.     else
  65.       writeln( "You are running out of food.." );
  66.     endif;
  67.   endif;
  68. endif;
  69.  
  70. ! Every quarter of an hour !
  71. L25 = max(MinutesInAnHour / 4 + 1,2);
  72. if NOT(minute % L25) then
  73.   ! Group must rest within 2 hours or start suffering damage !
  74.   if group.energy < MinutesInAnHour * 2 then 
  75.     if group.energy > 0 then
  76.       writeln( "You must rest soon.." );
  77.     else
  78.       writeln( "You are exhausted.." );
  79.     endif;
  80.   endif;
  81.   ! Check for poison, hunger and exhaustion !
  82.   foreach player do
  83.     if player.hp > 0 then
  84.       if player.poisoned then
  85.         s0 = "poisoning";
  86.         gosub HITPLAYER;
  87.       elsif player.energy = 0 and group.food = 0 then
  88.         s0 = "hunger";
  89.         gosub HITPLAYER;
  90.       elsif group.energy <= 0 then
  91.         s0 = "exhaustion";
  92.         gosub HITPLAYER;
  93.       endif;
  94.     endif;
  95.   endfor;
  96. endif;
  97.  
  98. ! Every other minute, restore some hit points !
  99. if minute % 2 = 0 and group.energy > 0 then
  100.   foreach player do
  101.     gosub HEAL_HP;
  102.     if minute % 4 = 0 then
  103.       gosub HEAL_PWR;
  104.     endif;
  105.   endfor;
  106. endif;
  107.  
  108. if world.type = ARENA and L254 = FALSE then
  109.   gosub NEWMONSTER;
  110. endif;
  111.  
  112. ! Go back with same selected spokesperson.. !
  113. group.current = L255;
  114. CONTINUE;
  115.  
  116. !---------------------------------------------------------------------------!
  117. :@1 ! Entry Point @1 : Party decides to rest (CAMP OUT)                     !
  118. !---------------------------------------------------------------------------!
  119. !
  120. ! First, all temporary magical effects are eliminated by reducing any 
  121. ! attribute that exceeds the maximum value for the same attribute.
  122. !
  123. ! Armor, Shields, Rings and Amulets re-apply their effect (if any).
  124. !
  125. ! The group rests for a third of a day, in one hour increments.  For
  126. ! each hour rested, the group gains 4 hours of 'wake-up' energy.  This
  127. ! means the group should be able to go one and a third days without 
  128. ! sleep.
  129. !
  130. ! Random monsters may appear, but not too often.
  131. !
  132.   write( "Resting.." );
  133.   L255 = group.current; ! Save current party spokesperson   !
  134.   L254 = FALSE;         ! Have NOT created a random monster !
  135.   foreach player do
  136.     ! First, get rid of temporary magical increases in attributes !
  137.     player.str = min(player.str,player.mstr);
  138.     player.aim = min(player.aim,player.maim);
  139.     player.dex = min(player.dex,player.mdex);
  140.     player.spd = min(player.spd,player.mspd);
  141.     player.pwr = min(player.pwr,player.mpwr);
  142.     player.hp  = min(player.hp, player.mhp);
  143.     player.iq  = min(player.iq, player.miq);
  144.     player.ac  = min(player.ac, player.mac);
  145.     if player.armor.count or player.shield.count then
  146.       if player.armor.cursed or player.shield.cursed then
  147.         player.ac = 0;
  148.       else
  149.         inc( player.ac, player.armor.ac + player.shield.ac );
  150.       endif;
  151.     endif;
  152.     if player.ring.count and player.ring.charges then
  153.       curritem = player.ring;
  154.       gosub M1_INVOKE;
  155.     endif;
  156.     if player.amulet.count and player.ring.charges then
  157.       curritem = player.amulet;
  158.       gosub M1_INVOKE;
  159.     endif;
  160.   endfor;
  161.   ! # of hours to rest is one third of a day !
  162.   for L253 = 1 to HoursInADay / 3 + 1 do 
  163.     ! Each hour of sleep gives 4 hours of energy !
  164.     inc( group.energy, MinutesInAnHour * 4 );
  165.     for L252 = 0 to MinutesInAnHour / 2 do
  166.       foreach player do
  167.         gosub HEAL_HP;
  168.         if L252 % 2 then
  169.           gosub HEAL_PWR;
  170.         endif;
  171.       endfor;
  172.     endfor;
  173.     ! Check to see if random monsters appear !
  174.     if world.type = OUTDOORS or world.type = DUNGEON or world.type = HAUNTED then
  175.       if random(17) = 0 then
  176.         gosub NEWMONSTER;
  177.         if L254 then
  178.           writeln( "You wake up under attack.." );
  179.           FIGHT;       ! Wake up and fight.. !
  180.         endif;
  181.       endif;
  182.     endif;
  183.   endfor;
  184.   group.current = L255; ! Go back to original spokes person !
  185.   STOP;
  186.  
  187. !---------------------------------------------------------------------------!
  188. :@2 ! Entry Point @2 : Leave Party                                          !
  189. !---------------------------------------------------------------------------!
  190. !
  191. ! The currently selected member is the one that will attempt to leave the
  192. ! party. 
  193. !
  194. ! NOTE: When the game player selects 'V'acate, he/she is asked to select
  195. ! which player. The script for the player is invoked if it has a :@DROP
  196. ! entry point. If the script terminates with CONTINUE or the script does
  197. ! NOT have an :@DROP entry, this script will be executed.
  198. !
  199.  
  200.   if player.index = 0 then
  201.     writeln( "YOU can't leave the party!" );
  202.     STOP;
  203.   endif;
  204.   if player.hp = 0 then
  205.     writeln( "You leave ", player.name, "'s body where it lays.." );
  206.   elsif player.hp < 2 then
  207.     writeln( "You abandon ", player.name, ", who is almost dead.." );
  208.   else
  209.     writeln( player.name, " leaves the group." );
  210.   endif;
  211.   LEAVE(player.index);
  212.   STOP;
  213.  
  214. !
  215. ! SUBROUTINE: HEAL_HP
  216. !
  217. ! Heal the players with the passage of time
  218. !
  219. :HEAL_HP
  220.   if player.hp > 0 and not player.poisoned then ! alive and not sick !
  221.     dec( player.energy );
  222.     if player.energy = 0 then
  223.       if group.food > 0 then
  224.         dec( group.food );
  225.         player.energy = 255;
  226.       else
  227.         writeln( player.name, " is hungry, but you have no food!" );
  228.         return;
  229.       endif;
  230.     endif;
  231.     if player.hp < player.mhp then
  232.       inc( player.hp );
  233.     endif;
  234.   endif;
  235.   return;
  236.  
  237. !
  238. ! SUBROUTINE: HEAL_PWR
  239. !
  240. ! Restore magic points withthe passage of time..
  241. !
  242. :HEAL_PWR
  243.   if player.hp > 0 and player.energy > 0 and player.pwr < player.mpwr then
  244.     inc( player.pwr );
  245.     if player.class = ELF and player.pwr < player.mpwr then
  246.       inc( player.pwr ); ! Do elves faster.. !
  247.     endif;
  248.   endif;
  249.   return;
  250.  
  251. !
  252. ! SUBROUTINE to create a Random Monster
  253. !
  254. :NEWMONSTER
  255.   ! Try to find a position for the monster up to 8 times..
  256.   for L3 = 1 to 8 do
  257.     L0 = group.x + random(8) - 4;
  258.     L1 = group.y + random(8) - 4;
  259.     if L0 < 0 then L0 = 0; endif;
  260.     if L1 < 0 then L1 = 0; endif;
  261.     if L0 >= world.x then L0 = world.x - 1; endif;
  262.     if L1 >= world.y then L1 = world.y - 1; endif;
  263.     if L0 <> player.x or L1 <> player.y then
  264.       L2 = world.density(L0,L1);
  265.       if L2 = FLAT or L2 = ROUGH or L2 = VERY_ROUGH then
  266.         ! Create a LAND-BASED monster !
  267.         L2 = random(3);    ! Small, Medium or Large (0-2) !
  268.         L3 = random(L2+3); ! Select a graphics block for that size (0-4) !
  269.         if world.type = DUNGEON then
  270.           L4 = DEFCAVEBLK( L3 );            ! Leader   !
  271.           L5 = DEFCAVEBLK( random(L3+1) );  ! Follower !
  272.           L6 = CAVE_MONSTER;
  273.         elsif world.type = HAUNTED then
  274.           L4 = DEFSPOOKBLK( L3 );           ! Leader   !
  275.           L5 = DEFSPOOKBLK( random(L3+1) ); ! Follower !
  276.           L6 = SPOOK_MONSTER;
  277.         else
  278.           ! OUTDOORS or ARENA !
  279.           L4 = DEFLANDBLK( L3 );            ! Leader   !
  280.           L5 = DEFLANDBLK( random(L3+1) );  ! Follower !
  281.           L6 = LAND_MONSTER;
  282.         endif;
  283.         goto DOIT;
  284.       elsif L2 = DEEP_WATER then
  285.         ! Create a WATER-BOUND monster !
  286.         L2 = random(3);        ! Small, Medium, Large (0-2) !
  287.         if random(5) = 0 then  ! Pirate Ship (SPECIAL CASE) !
  288.           L4 = DEFWATERBLK(4); ! Fifth water monster is a ship !
  289.           L5 = DEFWATERBLK(4); ! Followers are ships also !
  290.         else
  291.           L3 = random(L2+2); ! Select a graphics block for that size (0-3) !
  292.           L4 = DEFWATERBLK( L3 );            ! Leader   !
  293.           L5 = DEFWATERBLK( random(L3+1) );  ! Follower !
  294.         endif;
  295.         L6 = WATER_MONSTER;
  296.         goto DOIT;
  297.       endif;
  298.     endif;
  299.   endfor;
  300.   return; ! Tried 8 Times, give up !
  301.  
  302. :DOIT
  303.   new(npc,L0,L1,L4);
  304.   npc.type   = HOSTILE;       ! NPC Type
  305.   npc.stats  = defstat(L2);   ! Statistics Record
  306.   npc.block2 = L5;            ! Followers (if any)
  307.   npc.class  = L6;            ! Monster Class
  308.  
  309.   ! Gold carried
  310.   if world.type = ARENA then
  311.     npc.value = random(50)+1; ! Very little money (Up to 5 gold pieces) !
  312.   else
  313.     npc.value = 0;
  314.   endif;
  315.  
  316.   !
  317.   ! # of monsters in the group.  The formula is based on L2 (monster size).
  318.   ! If small  (L2=0), then # = random( group.size + 6 ) + 1
  319.   ! If medium (L2=1), then # = random( group.size + 3 ) + 1
  320.   ! if large  (L2=2), then # = random( group.size ) + 1
  321.   npc.count = random( group.size + (2 - L2) * 3 ) + 1;
  322.  
  323.   L254 = TRUE; ! Monster has been created !
  324.   return;
  325.  
  326. !
  327. ! This SUBROUTINE will hit every player in the group by using the
  328. ! subroutine HITPLAYER.
  329. !
  330. :HITGROUP
  331.   foreach player do
  332.     gosub HITPLAYER;
  333.   endfor;
  334.   return;
  335.  
  336. !
  337. ! This SUBROUTINE will decrement the hit points of the current
  338. ! group member.  It checks to see if the player has died or lost
  339. ! consciousnes.  The variable S0 contains the reason for the hit.
  340. !
  341. :HITPLAYER
  342.   if player.hp > 0 then
  343.     dec( player.hp );
  344.     if player.hp = 0 then
  345.       writeln( player.name, " has died of ", s0, "!" );
  346.     elsif player.hp = 1 then
  347.       writeln( player.name, " has fainted from ", s0, "!" );
  348.     else
  349.       writeln( player.name, " weakens!" );
  350.     endif;
  351.   endif;
  352.   return;
  353.  
  354.  
  355. !------------------------------------------------------------------------!
  356. !
  357. ! SUBROUTINE: M1_INVOKE
  358. !
  359. ! Type 1 Magic - Affects the person invoking the magic..
  360. !
  361. ! This code is equivalent to the one in OBJECT.SCR.  When resting, 
  362. ! rings and amulets that have magical properties will re-invoke their
  363. ! effect when you wake up.
  364. !
  365. !------------------------------------------------------------------------!
  366. :M1_INVOKE
  367. !------------------------------------------------------------------------!
  368.  
  369.   if curritem.cursed then
  370.     if curritem.permanent then
  371.       writeln( "WARNING: Cursed Item with permanent effect not recommended!");
  372.       curritem.permanent = FALSE;
  373.     endif;
  374.   endif;
  375.  
  376.   if curritem.charges < 255 then
  377.     dec(curritem.charges);  ! 255 means forever !
  378.   endif;
  379.  
  380.   on curritem.class goto
  381.     M1_NONE,    M1_CURE,    M1_HEAL,    M1_POISON,    M1_RESTORE,
  382.     M1_STR,     M1_DEX,     M1_SPD,     M1_AIM,       M1_AC,
  383.     M1_HP,      M1_IQ,      M1_PWR;
  384.  
  385. :M1_NONE
  386.   return;
  387.  
  388. :M1_CURE
  389.   if player.poisoned then
  390.     player.poisoned = 0;
  391.     writeln( player.name, " is now cured." );
  392.   endif;
  393.   return;
  394.  
  395. :M1_HEAL
  396.   if player.hp > 0 and player.hp < player.mhp then
  397.     if curritem.units > 0 then
  398.       L0 = curritem.units;                   ! always heals the same points !
  399.     else
  400.       L0 = random(player.mhp - player.hp)+1; ! heal a random number of points !
  401.     endif;
  402.     if player.hp + L0 < player.mhp then
  403.       writeln( player.name, " heals ", L0, " hit points.." );
  404.       inc( player.hp, L0 );
  405.     else
  406.       writeln( player.name, " has been completely healed!" );
  407.       player.hp = player.mhp;
  408.     endif;
  409.   endif;
  410.   return;
  411.  
  412. :M1_POISON
  413.   if NOT player.poisoned then
  414.     player.poisoned = TRUE;
  415.     writeln( player.name, " is poisoned!" );
  416.   endif;
  417.   return;
  418.  
  419. :M1_RESTORE
  420.   if player.hp < player.mhp then
  421.     player.hp = player.mhp;
  422.     writeln( player.name, " is completely healed!" );
  423.   endif;
  424.   return;
  425.  
  426. :M1_STR
  427.   if curritem.cursed then
  428.     player.str = 0;
  429.   else
  430.     inc( player.hp, curritem.units );
  431.     if curritem.permanent then
  432.       inc( player.mhp, curritem.units );
  433.     endif;
  434.     writeln( player.name, "'s strength increased by ", curritem.units, "!" );
  435.   endif;
  436.   return;
  437.  
  438. :M1_DEX
  439.   if curritem.cursed then
  440.     player.dex = 0;
  441.   else
  442.     inc( player.dex, curritem.units );
  443.     if curritem.permanent then
  444.       inc( player.mdex, curritem.units );
  445.     endif;
  446.     writeln( player.name, "'s dexterity increased by ", curritem.units, "!" );
  447.   endif;
  448.   return;
  449.  
  450. :M1_SPD
  451.   if curritem.cursed then
  452.     player.spd = 0;
  453.   else
  454.     inc( player.spd, curritem.units );
  455.     if curritem.permanent then
  456.       inc( player.mspd, curritem.units );
  457.     endif;
  458.     writeln( player.name, "'s speed increased by ", curritem.units, "!" );
  459.   endif;
  460.   return;
  461.  
  462. :M1_AIM
  463.   if curritem.cursed then
  464.     player.aim = 0;
  465.   else
  466.     inc( player.aim, curritem.units );
  467.     if curritem.permanent then
  468.       inc( player.maim, curritem.units );
  469.     endif;
  470.     writeln( player.name, "'s aim increased by ", curritem.units, "!" );
  471.   endif;
  472.   return;
  473.  
  474. :M1_AC
  475.   if curritem.cursed then
  476.     player.ac = 0;
  477.   else
  478.     inc( player.ac, curritem.units );
  479.     if curritem.permanent then
  480.       inc( player.mac, curritem.units );
  481.     endif;
  482.     writeln( player.name, "'s armor class increased by ", curritem.units, "!" );
  483.   endif;
  484.   return;
  485.  
  486. :M1_HP
  487.   if curritem.cursed then
  488.     player.hp = player.hp / 3 + 1;
  489.   else
  490.     inc( player.hp, curritem.units );
  491.     if curritem.permanent then
  492.       inc( player.mhp, curritem.units );
  493.     endif;
  494.     writeln( player.name, "'s hit points increased by ", curritem.units, "!" );
  495.   endif;
  496.   return;
  497.  
  498. :M1_IQ
  499.   if curritem.cursed then
  500.     player.iq = 0;
  501.   else
  502.     inc( player.iq, curritem.units );
  503.     if curritem.permanent then
  504.       inc( player.miq, curritem.units );
  505.     endif;
  506.     writeln( player.name, "'s i.q. increased by ", curritem.units, "!" );
  507.   endif;
  508.   return;
  509.  
  510. :M1_PWR
  511.   if player.class = ELF or player.class = WIZARD then
  512.     if curritem.cursed then
  513.       player.pwr = 0;
  514.     else
  515.       inc( player.pwr, curritem.units );
  516.       if curritem.permanent then
  517.         inc( player.mpwr, curritem.units );
  518.       endif;
  519.       writeln( player.name, "'s power increased by ", curritem.units, "!" );
  520.     endif;
  521.   else
  522.     write( player.name, " has a headache all night long.." );
  523.     if player.hp < 3 then
  524.       writeln( " and dies!" );
  525.       player.hp = 0;
  526.     else
  527.       writeln;
  528.       dec( player.hp, 2 );
  529.     endif;
  530.   endif;
  531.   return;
  532.     
  533.  
  534.